package APIs.twitter;

// This package depends heavily on Twitter4J and Twitpic4J
// Twitter4J: http://twitter4j.org/en/index.html
// Twitpic4J: http://code.google.com/p/twitpic4j/

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.util.List;
import java.util.Vector;

import twitter4j.*;

public class TwitterLink {
	    
	   /**
	    * Downloads images from a twitter user and places them at the provided location.
	    * @param username
	    * @param diskLocation
	    * @throws TwitterException
	    * @throws IOException
	    */
	    public static void downloadImages(String username, String diskLocation, boolean newFilesOnly) throws TwitterException, IOException {
	    	// First we have to download the timeline
	    	Object [] test = downloadTimeline(username);
	    	
	    	// Grab the links from the twitter feed
	    	String [] links = parseLinks(test);
	    	
	    	// Convert the links from the short form to the long form
	    	Vector<String> longLinks = new Vector<String>();
	    	for(int i = 0; i < links.length; i++) {
	    		try {
		    		links[i] = expandShortURL("http://" + links[i].toString());
		    		
		    		// we will also remove any link not associated with imgur
		    		if(links[i].toString().contains("imgur.com")) {
		    			longLinks.add(links[i].toString());
		    		}
	    		} catch(Exception e) {
	    			e.printStackTrace();
	    		}
	    	}
	    	
	    	for(int i = 0; i < longLinks.size(); i++) {
	    		try {
	    	    	if(!newFilesOnly || (newFilesOnly && FileManipulation.isNewFile(FileManipulation.parseFilename(links[i]), username))) {
		    			// Write the image to the disk
		    			FileManipulation.writeImageToDisk(longLinks.get(i), diskLocation, parseFiletype(longLinks.get(i)),username);
		    		}
	    		} catch (Exception e) {
	    			e.printStackTrace();
	    		}
	    	}
	    }
	    
		   /**
		    * Downloads images from a twitter user and places them at the provided location.
		    * @param username
		    * @param diskLocation
		    * @throws TwitterException
		    * @throws IOException
		    */
		    public static Vector<String> downloadImageNames(String username,boolean newFilesOnly) throws TwitterException, IOException {
		    	Vector<String> retVal = new Vector<String>();
		    	// First we have to download the timeline
		    	Object [] test = downloadTimeline(username);
		    	
		    	// Grab the links from the twitter feed
		    	String [] links = parseLinks(test);
		    	
		    	// Convert the links from the short form to the long form
		    	Vector<String> longLinks = new Vector<String>();
		    	for(int i = 0; i < links.length; i++) {
		    		try {
			    		links[i] = expandShortURL("http://" + links[i].toString());
			    		
			    		// we will also remove any link not associated with imgur
			    		if(links[i].toString().contains("imgur.com")) {
			    			longLinks.add(links[i].toString());
			    		}
		    		} catch(Exception e) {
//		    			System.err.println("Could not expand:" + links[i].toString());
		    		}
		    	}
		    	
		    	for(int i = 0; i < longLinks.size(); i++) {
		    		try {
		    			// We need to convert twitter links to AWS links		    		
		    			if(!newFilesOnly || (newFilesOnly && FileManipulation.isNewFile(FileManipulation.parseFilename(links[i]), username))) {
			    			retVal.add(FileManipulation.parseFilename(links[i]) + "|" + links[i]);
		    			}
		    		} catch (Exception e) {
		    			//e.printStackTrace();
		    		}
		    	}
		    	
		    	return retVal;
		    }	    
	    
	    /**
	     * Uploads the image to imgur and the message to twitter via OAuth calls
	     * @param username username to upload to
	     * @param password password for twitter user
	     * @param filename file to upload
	     * @param message message to associate with file
	     */
	    public static void uploadImage(String username, String password, String filename, String message) throws Exception {
	    	String finalMessage = message; // this will be the final message we post to twitter
	    	
	    	// we need to first upload to imgur and grab the link
	    	String imgurLink = ImgurMain.uploadToImgur(filename);
	    	
	    	// Then we will append the link to our twitter update
	    	finalMessage += " " + imgurLink;
	    	
	    	// This will update twitter with our final message
			OAuthMain.updateExistingUser(username, finalMessage);
	    }
	    
	    /**
	     * Downloads the timeline for a given twitter user
	     * @param username user to grab timeline for
	     * @throws TwitterException 
	     */
	    public static Object[] downloadTimeline(String username) throws TwitterException {
	    	Vector<String> rVal = new Vector<String>();
	    	
	         // The factory instance is re-useable and thread safe.
	        Twitter twitter = new TwitterFactory().getInstance();
	        List<Status> statuses = twitter.getUserTimeline(username);
	        for (Status status : statuses) {
	            rVal.add(status.getUser().getName() + ":" + status.getText());
	        }
	        
	        return rVal.toArray();
	    }

	    /**
	     * Expands a shortened URL.
	     * @param address
	     * @return
	     * @throws IOException
	     * This function primary solves the HTTP 301 issue 
	     */
		public static String expandShortURL(String address) throws IOException {
		    URL url = new URL(address);
		
		    HttpURLConnection connection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); //using proxy may increase latency
		    connection.setInstanceFollowRedirects(false);
		    connection.connect();
		    String expandedURL = connection.getHeaderField("Location");
		    connection.getInputStream().close();
		    return expandedURL;
		}

		/**
		 * Parses links out of twitter feeds.
		 * @param in
		 * @return
		 */
		public static String[] parseLinks(Object[] in) {
			// This vector will temporarily store our strings
			String []out = new String[in.length];
			
			for(int i = 0; i < in.length; i++) {
				String b1 = in[i].toString();
				//System.out.println("status: " + b1);
				if(b1.contains("http://")) {
//					System.out.println("link: " + b1);
					String b2 = b1.split("http://")[1];
					out[i] = b2;
				}
			}
			
			return out;
		}
		
		public static String parseFiletype(String link) {
			String retVal = "";
			try {
			retVal = link.split(".com/")[1];
			retVal = retVal.split("\\.")[1];
			} catch(Exception e) {
				e.printStackTrace();
			}
			
			return retVal;
		}
}
